package com.wxzz.elearing.course.amqp.consume;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rabbitmq.client.Channel;
import com.wxzz.elearing.course.amqp.producer.CourseProducer;
import com.wxzz.elearing.course.entity.StudyPlan;
import com.wxzz.elearing.course.entity.TrainSurvey;
import com.wxzz.elearing.course.entity.WxUserStudyPlan;
import com.wxzz.elearing.course.mapper.StudyPlanMapper;
import com.wxzz.elearing.course.mapper.TrainSurveyMapper;
import com.wxzz.elearing.course.mapper.WxUserStudyPlanMapper;
import com.wxzz.elearning.common.bean.RabbitMQConfiguration;
import com.wxzz.elearning.common.bean.SmsConfig;
import com.wxzz.elearning.common.constants.RabbitPool;
import com.wxzz.elearning.common.constants.RedisConstants;
import com.wxzz.elearning.common.dto.FeignOperationLogDto;
import com.wxzz.elearning.common.dto.SystemMessageMqDto;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class CourseListener {

    private static final Logger logger = LoggerFactory.getLogger(CourseListener.class);

    @Autowired
    private WxUserStudyPlanMapper wxUserStudyPlanMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @RabbitListener(queues = RabbitMQConfiguration.WXZZ_COURSE_DELAY_QUEUE)
    public void onDelayMessage(@Payload String msg,
                               @Headers Map<String, Object> headers,
                               Channel channel, Message message) throws IOException {
        logger.info("监听延时交换机, 收到消息: {}", message);
        Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
            this.process(msg); // 内部处理
        } catch (Exception e) {
            boolean redelivered = (boolean) headers.get(AmqpHeaders.REDELIVERED);
            channel.basicNack(deliveryTag, false, !redelivered);
        }
    }

    /**
     * 课程同步
     *
     * @param msg
     * @param channel
     * @param message
     * @throws IOException
     */
//    @RabbitListener(queues = RabbitPool.COURSE_UPDATE_QUEUE)
//    public void direct(String msg, Channel channel, Message message) throws IOException {
//
//    }

    @Autowired
    private StudyPlanMapper studyPlanMapper;


    @Autowired
    private CourseProducer courseProducer;

    private void process(String msg) {
        // log.info("livetelecastQueue 接收时间:{} 接收内容:{}", LocalDateTime.now().toString(), msg);
        JSONObject map = JSON.parseObject(msg);
        //消息唯一标识
        String uuid = redisTemplate.opsForValue().get(RedisConstants.DEAL_QUEUE_LIVETELECAST + map.get("id") + map.get("type") + map.get("status"));
        //验证
        if (map.get("uuid").equals(uuid)) {
            //todo 小程序订阅
            if (RabbitMQConfiguration.QUEUE_TYPE4.equals(map.get("type"))) {
                // 学习计划即将到期提醒
                StudyPlan studyPlan = studyPlanMapper.selectById(map.getLong("id"));
                if (studyPlan != null) {
                    List<WxUserStudyPlan> wxUserStudyPlans = wxUserStudyPlanMapper.selectList(new LambdaQueryWrapper<WxUserStudyPlan>()
                            .eq(WxUserStudyPlan::getStudyPlanId, studyPlan.getId()).select(WxUserStudyPlan::getWxUserId));
                    List<Long> wxUserIds = new ArrayList<>();
                    wxUserStudyPlans.stream().forEach(p -> wxUserIds.add(p.getWxUserId()));
                    SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
                    systemMessageMqDto.setMessageDetail("您的" + studyPlan.getPlanName() + "学习计划将于" + studyPlan.getFinishTime() + "到期,请尽快学习");
                    systemMessageMqDto.setMessageTitle("学习计划即将到期");
                    systemMessageMqDto.setWxUserIds(wxUserIds);
                    courseProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
                    logger.info("服务消费-id为:{}的学习计划即将到期提醒成功", map.get("id"));
                } else {
                    logger.error("服务消费-id为:{}的学习计划即将到期提醒失败，原因 id数据查询不存在", map.get("id"));
                }
            } else if (RabbitMQConfiguration.QUEUE_TYPE5.equals(map.get("type"))) {
                // 学习计划到期提醒
                StudyPlan studyPlan = studyPlanMapper.selectById(map.getLong("id"));
                if (studyPlan != null) {
                    List<WxUserStudyPlan> wxUserStudyPlans = wxUserStudyPlanMapper.selectList(new LambdaQueryWrapper<WxUserStudyPlan>()
                            .eq(WxUserStudyPlan::getStudyPlanId, studyPlan.getId()).select(WxUserStudyPlan::getWxUserId));
                    List<Long> wxUserIds = new ArrayList<>();
                    wxUserStudyPlans.stream().forEach(p -> wxUserIds.add(p.getWxUserId()));
                    SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
                    systemMessageMqDto.setMessageDetail("您的" + studyPlan.getPlanName() + "学习计划将于" + studyPlan.getFinishTime() + "到期,请及时完成学习");
                    systemMessageMqDto.setMessageTitle("学习计划已到期");
                    systemMessageMqDto.setWxUserIds(wxUserIds);
                    courseProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
                    logger.info("服务消费-id为:{}的学习计划到期提醒成功", map.get("status"));
                } else {
                    logger.error("服务消费-id为:{}的学习计划到期提醒失败，原因 id查询不存在", map.get("id"));
                }
            } else if (RabbitMQConfiguration.QUEUE_TYPE10.equals(map.get("type"))) {
                // 培训计划状态修改
                TrainSurvey trainSurvey = trainSurveyMapper.selectById(map.getLong("id"));
                if (trainSurvey != null) {
                    trainSurvey.setStatus(map.getInteger("status"));
                    trainSurveyMapper.updateById(trainSurvey);
                    logger.info("服务消费-id为:{}的培训计划状态修改成功", map.get("status"));
                } else {
                    logger.error("服务消费-id为:{}的培训计划状态修改失败，原因 id查询不存在", map.get("id"));
                }
            } else {
                logger.error("服务消费-id为:{}的消费类型不存在：{}", map.get("id"), map.get("type"));
            }
        } else {
            logger.error("服务消费-失败：uuid不匹配：{}，{}", uuid, map.get("uuid"));
        }
    }

    @Autowired
    private TrainSurveyMapper trainSurveyMapper;

}
